package com.qys.livesMall.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.common.utils.MessageUtils;
import com.qys.livesMall.framework.utils.SecurityUtils;
import com.qys.livesMall.product.entity.*;
import com.qys.livesMall.product.entity.query.RequestData;
import com.qys.livesMall.product.mapper.H2ProductCategoryMapper;
import com.qys.livesMall.product.mapper.H2ProductGoodsinfoMapper;
import com.qys.livesMall.product.mapper.H2ProductSkuAttributeMapper;
import com.qys.livesMall.product.mapper.H2ProductSkuMapper;
import com.qys.livesMall.product.model.H2ProductGoodsinfoDto;
import com.qys.livesMall.product.service.H2ProductGoodsinfoService;
import com.qys.livesMall.product.service.H2ProductSkuAttributeService;
import com.qys.livesMall.product.service.H2ProductSkuService;
import com.qys.livesMall.product.service.ProductSkuAttributeOptionsService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author gmx
 * @since 2023-05-17
 */
@Service
public class H2ProductGoodsinfoServiceImpl extends ServiceImpl<H2ProductGoodsinfoMapper, H2ProductGoodsinfo> implements H2ProductGoodsinfoService {
    @Resource
    private H2ProductGoodsinfoMapper spuMapper;

    @Resource
    private H2ProductSkuMapper skuMapper;
    @Resource
    private H2ProductCategoryMapper categoryMapper;
    @Resource
    private H2ProductSkuService skuService;
    @Resource
    H2ProductSkuAttributeService skuAttributeService;
    @Resource
    ProductSkuAttributeOptionsService optionsService;
    @Resource
    H2ProductSkuAttributeMapper shopSkuAttributeMapper;
    @Override
    @Transactional(rollbackFor={Exception.class})
    public R<Long> saveProduct(H2ProductProduct h2ProductProduct) {
        H2ProductGoodsinfo spu = h2ProductProduct.getH2ProductGoodsinfo();

        if (ObjectUtils.isNull(spu)){
            throw new QysException("product.spu.null");
        }
        spu.setNum(0);
        //上架
        spu.setIsMarketable(Constants.YesNoInt.NO);
        //未删除
        spu.setIsDelete(Constants.YesNoInt.NO);
        //状态
        spu.setStatus(1);
        //添加
        spu.setCreateTime(LocalDateTime.now());
        spu.setCreateBy(SecurityUtils.getUsername());
        spu.setUpdateTime(LocalDateTime.now());
        spu.setUpdateBy(SecurityUtils.getUsername());
        //校验分类
        H2ProductCategory category = categoryMapper.selectById(spu.getCategoryTwoId());
        if (ObjectUtils.isEmpty(category)){
            throw new QysException(MessageUtils.message("categories.that.don't.exist"));
        }

        boolean add=save(spu);
        if (!add){
            throw new QysException(MessageUtils.message("add.goods.failed"));
        }

        List<H2ProductSkuAttribute> attributes =h2ProductProduct.getH2ProductSkuAttributeList();
        for (H2ProductSkuAttribute attribute : attributes) {
            attribute.setSpuId(spu.getId());
            if (!skuAttributeService.save(attribute)) throw new QysException(MessageUtils.message("attribute.binding.failure"));
        }
        return R.ok(spu.getId());

    }

    @Override
    public void upd(H2ProductProduct h2ProductProduct){

        H2ProductGoodsinfo spu = h2ProductProduct.getH2ProductGoodsinfo();
        if (ObjectUtils.isNull(spu)||ObjectUtils.isNull(spu.getId())){
            throw new QysException("product.spu.null");
        }
        spu.setUpdateTime(LocalDateTime.now());
        spu.setUpdateBy(SecurityUtils.getUsername());
        if (!updateById(spu)){
            throw new QysException(MessageUtils.message("add.goods.failed"));
        }
        updateById(spu);
    }

    @Override
    public R<H2ProductProduct> product(Long id) {
        H2ProductProduct h2ProductProduct = new H2ProductProduct();
        H2ProductGoodsinfo spu=spuMapper.selectById(id);
        if(ObjectUtils.isEmpty(spu)){
            return R.fail(MessageUtils.message("goods.does.not.exist"));
        }
        List<H2ProductSku> sku = skuMapper.selectList(new QueryWrapper<H2ProductSku>().lambda().eq(H2ProductSku::getSpuId, id));
//        List<H2ProductSkuAttribute> h2ProductSkuAttributes = shopSkuAttributeMapper.selectList(new QueryWrapper<H2ProductSkuAttribute>().lambda().eq(H2ProductSkuAttribute::getSpuId, id));
        LambdaQueryWrapper<H2ProductSkuAttribute> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(H2ProductSkuAttribute::getSpuId, id);
        List<H2ProductSkuAttribute> attributeList = skuAttributeService.list(queryWrapper);

        for (H2ProductSkuAttribute attribute : attributeList) {
            LambdaQueryWrapper<ProductSkuAttributeOptions> optionQueryWrapper = new LambdaQueryWrapper<>();
            optionQueryWrapper.eq(ProductSkuAttributeOptions::getAttrId, attribute.getId());
            List<ProductSkuAttributeOptions> optionList = optionsService.list(optionQueryWrapper);
            attribute.setOptions(optionList);
        }
        h2ProductProduct.setH2ProductGoodsinfo(spu);
        h2ProductProduct.setH2ProductSkuList(sku);
        h2ProductProduct.setH2ProductSkuAttributeList(attributeList);
        return R.ok(h2ProductProduct);
    }

    @Override
    public R<H2ProductProduct> appProduct(Long id) {
        H2ProductProduct h2ProductProduct = new H2ProductProduct();
        LambdaQueryWrapper<H2ProductGoodsinfo> goodsinfoQueryWrapper = new LambdaQueryWrapper<>();
        H2ProductGoodsinfo query = new H2ProductGoodsinfo();
        query.setId(id);
        query.setIsDelete(0);
        query.setIsMarketable(1);
        query.setStatus(1);
        goodsinfoQueryWrapper.setEntity(query);
        H2ProductGoodsinfo spu=spuMapper.selectOne(goodsinfoQueryWrapper);
        if(ObjectUtils.isEmpty(spu)){
            return R.fail(MessageUtils.message("goods.does.not.exist"));
        }
        List<H2ProductSku> sku = skuMapper.selectList(new QueryWrapper<H2ProductSku>().lambda().eq(H2ProductSku::getSpuId, id).eq(H2ProductSku::getStatus,1));
        LambdaQueryWrapper<H2ProductSkuAttribute> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(H2ProductSkuAttribute::getSpuId, id);
        List<H2ProductSkuAttribute> attributeList = skuAttributeService.list(queryWrapper);

        for (H2ProductSkuAttribute attribute : attributeList) {
            LambdaQueryWrapper<ProductSkuAttributeOptions> optionQueryWrapper = new LambdaQueryWrapper<>();
            optionQueryWrapper.eq(ProductSkuAttributeOptions::getAttrId, attribute.getId());
            List<ProductSkuAttributeOptions> optionList = optionsService.list(optionQueryWrapper);
            attribute.setOptions(optionList);
        }
        h2ProductProduct.setH2ProductGoodsinfo(spu);
        h2ProductProduct.setH2ProductSkuList(sku);
        h2ProductProduct.setH2ProductSkuAttributeList(attributeList);
        return R.ok(h2ProductProduct);
    }

    @Override
    public R<IPage<H2ProductGoodsinfo>> listPageByCatid(Page<H2ProductGoodsinfo> page) {
        LambdaQueryWrapper<H2ProductGoodsinfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(H2ProductGoodsinfo::getIsDelete,0);
        if (ObjectUtils.isNotNull(page.getRecords())){
            try {
                H2ProductGoodsinfo r = page.getRecords().get(0);
                if (ObjectUtils.isNotEmpty(r.getName())){
                    queryWrapper.like(H2ProductGoodsinfo::getName,r.getName());
                }
//                H2ProductGoodsinfo h2ProductGoodsinfo = new H2ProductGoodsinfo();
//                BeanUtil.copyProperties(r, h2ProductGoodsinfo, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
//                queryWrapper.setEntity(h2ProductGoodsinfo);
            }catch (Exception e){
               return R.fail(MessageUtils.message("system.error"));
            }
        }
        queryWrapper.orderByAsc(H2ProductGoodsinfo::getNum);
        Page<H2ProductGoodsinfo> data = page(page, queryWrapper);
        return R.ok(data);
    }
    public R<IPage<H2ProductGoodsinfoDto>> appListPageByCatid(RequestData<H2ProductGoodsinfo> data) {
        LambdaQueryWrapper<H2ProductGoodsinfo> queryWrapper = new LambdaQueryWrapper<>();
        H2ProductGoodsinfo h2ProductGoodsinfo = new H2ProductGoodsinfo();
        H2ProductGoodsinfo r;
        r = data.getData();
//        BeanUtil.copyProperties(r, h2ProductGoodsinfo, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
//        h2ProductGoodsinfo.setIsDelete(0);
//        h2ProductGoodsinfo.setIsMarketable(1);
//        h2ProductGoodsinfo.setStatus(1);
//        queryWrapper.setEntity(h2ProductGoodsinfo);
        queryWrapper.eq(H2ProductGoodsinfo::getIsDelete,"0");
        queryWrapper.eq(H2ProductGoodsinfo::getIsMarketable,"1");
        queryWrapper.eq(H2ProductGoodsinfo::getStatus,"1");
        if (ObjectUtils.isNotEmpty(r)){
            if (ObjectUtils.isNotEmpty(r.getCategoryOneId())){
                queryWrapper.like(H2ProductGoodsinfo::getCategoryOneId,r.getCategoryOneId());
            }
            if (ObjectUtils.isNotEmpty(r.getCategoryTwoId())){
                queryWrapper.like(H2ProductGoodsinfo::getCategoryTwoId,r.getCategoryTwoId());
            }
            if (ObjectUtils.isNotEmpty(r.getName())){
                queryWrapper.like(H2ProductGoodsinfo::getName,r.getName());
            }
        }
        Page<H2ProductGoodsinfo> res = page(data.getPage(), queryWrapper);
        Page<H2ProductGoodsinfoDto> page = new Page<>();
        page.setRecords(new ArrayList<H2ProductGoodsinfoDto>());
        for (H2ProductGoodsinfo record : res.getRecords()) {
            H2ProductGoodsinfoDto goodsinfoDto = new H2ProductGoodsinfoDto();
            BeanUtil.copyProperties(record,goodsinfoDto);
            goodsinfoDto.setSkuCountPrice(skuMapper.sumPriceBySpuId(record.getId().toString()));
            page.getRecords().add(goodsinfoDto);
        }
        return R.ok(page);
    }

    @Override
    public R delete(Long id) {
        H2ProductGoodsinfo spu=spuMapper.selectById(id);
        if (ObjectUtils.isEmpty(spu)){
            return R.fail(MessageUtils.message("goods.does.not.exist"));
        }
        spu.setIsDelete(spu.getIsDelete() == 1 ? 0 : 1);
        int row = spuMapper.updateById(spu);
        if (row<1){
            return R.fail(MessageUtils.message("goods.delete.error"));
        }
        return R.ok();
    }

    @Override
    public R marketable(Long id) {
        H2ProductGoodsinfo spu=spuMapper.selectById(id);
        if (ObjectUtils.isEmpty(spu)){
            return R.fail(MessageUtils.message("goods.does.not.exist"));
        }
        spu.setIsMarketable(spu.getIsMarketable()== 1 ? 0 : 1);
        int row = spuMapper.updateById(spu);
        if (row<1){
            return R.fail(MessageUtils.message("unmount.failure"));
        }
        return R.ok();
    }
}
